/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import com.google.common.eventbus.DeadEvent;
import java.util.ArrayList;
import java.util.List;
import model.Dapcomposition;
import model.Dapversion;
import model.Decision;
import model.Department;
import model.Docversion;
import model.Employee;
import model.Stepvalidation;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import util.ProjetHibernateUtil;

/**
 *
 * @author phinguyen
 */
public class StepOwnerCore {

    /**
     * store the hibernate session for the step owner core
     */
    private static Session session;

    public StepOwnerCore() {
        session = ProjetHibernateUtil.getSessionFactory().openSession();
    }

    /**
     * creation of a new employee and attribution to a Department
     *
     * @param department
     * @param name
     * @param firstname
     * @param email
     * @param pwd
     */
    public void addEmployee(Department department, String name, String firstname, String email, String pwd) {
        Employee employee = new Employee(department, name, firstname, email, pwd);
        Transaction tr = session.beginTransaction();
        session.saveOrUpdate(employee);
        tr.commit();
    }

    /**
     * move an employee from a department to an other
     *
     * @param department
     * @param employee
     */
    public void moveEmployee(Department department, Employee employee) {
        employee.setDepartment(department);
        Transaction tr = session.beginTransaction();
        session.saveOrUpdate(employee);
        tr.commit();
    }


    /**
     * return the department for an id
     * @param id
     * @return 
     */
    public Department researchDepartmentById(String id) {
        return (Department) session.get(Department.class, id);
    }

    /**
     * return the department for an name
     * @param name
     * @return 
     */
    public Department researchDepartmentByName(String name) {
        for (Department department : this.getAllDepartment()) {
            if (department.getDeptname().equals(name)) {
                return department;
            }
        }
        return null;
    }

    /**
     * return all employees linked with a department research by his name
     * @param department
     * @return 
     */
    public List<Employee> getAllEmployeesOfDepartmentResearchedByName(String department) {
        return getAllEmployeesOfDepartment(researchDepartmentByName(department));
    }

    /**
     * return all departments. It will call an HQL query in Hibernate
     * Department's mapping
     *
     * @return
     */
    public List<Department> getAllDepartment() {
        Query query = session.getNamedQuery("HQL_ALL_DEPARTMENT");
        List<Department> listAllDepartment = query.list();
        return listAllDepartment;
    }

    /**
     * return all employees of a department
     *
     * @param department
     * @return
     */
    public List<Employee> getAllEmployeesOfDepartment(Department department) {
        List<Employee> lstResult = new ArrayList();
        for (Employee employee : this.getAllEmployees()) {
            if (employee.getDepartment().equals(department)) {
                lstResult.add(employee);
            }
        }
        return lstResult;
    }

    /**
     * return all employees
     * @return 
     */
    public List<Employee> getAllEmployees() {
        Query query = session.getNamedQuery("HQL_ALL_EMPLOYEE");
        List result = query.list();
        return result;
    }

    /**
     * return all emails of employees
     *
     * @return
     */
    public List<String> getAllEmailEmployee() {
        Query query = session.getNamedQuery("HQL_ALL_EMAILEMPLOYEE");
        List result = query.list();
        return result;
    }

    /**
     * return an employee by his mail
     * @param mail
     * @return 
     */
    public Employee getEmployeeByMail(String mail) {
        for (Employee employee : this.getAllEmployees()) {
            if (employee.getEmail().equals(mail)) {
                return employee;
            }
        }
        return null;
    }

    /**
     * set up the right of validation of a table of employees
     * @param employees 
     */
    public void giveEmployeeValidationRights(String[] employees) {
        for (String idEmployee : employees) {
            Employee curentEmployee = this.getEmployeeById(idEmployee);
            curentEmployee.setEcanvalidate(true);
            Transaction tr = session.beginTransaction();
            session.saveOrUpdate(curentEmployee);
            tr.commit();
        }
    }

    /**
     * set up the right of validation of a list of employees
     * @param employees 
     */
    public void giveEmployeeValidationRights(List<Employee> employees) {
        for (Employee employee : employees) {
            employee.setEcanvalidate(true);
            Transaction tr = session.beginTransaction();
            session.saveOrUpdate(employee);
            tr.commit();
        }
    }

    /**
     * close rights of validation for a list of employees
     * @param employees 
     */
    public void removeEmployeeValidationRights(List<Employee> employees) {
        for (Employee employee : employees) {
            employee.setEcanvalidate(false);
            Transaction tr = session.beginTransaction();
            session.saveOrUpdate(employee);
            tr.commit();
        }
    }

    /**
     * return an employee by his id
     * @param idEmployee
     * @return 
     */
    private Employee getEmployeeById(String idEmployee) {
        for (Employee employee : this.getAllEmployees()) {
            if (employee.getEid().toString().equals(idEmployee)) {
                return employee;
            }
        }
        return null;
    }

    /**
     * close rights of validation for a table of employees
     * @param idEmployees 
     */
    public void revokeEmployeeValidationRights(String[] idEmployees) {
        for (String idEmployee : idEmployees) {
            Employee curentEmployee = this.getEmployeeById(idEmployee);
            curentEmployee.setEcanvalidate(false);
            Transaction tr = session.beginTransaction();
            session.saveOrUpdate(curentEmployee);
            tr.commit();
        }
    }

    /**
     * delete all employees of the table in parameter
     * @param idEmployees 
     */
    public void deleteEmployee(String[] idEmployees) {
        for (String idEmployee : idEmployees) {
            Employee curentEmployee = this.getEmployeeById(idEmployee);
            Transaction tr = session.beginTransaction();
            session.delete(curentEmployee);
            tr.commit();
        }
    }

    /**
     * return all current decisions
     * @param employee
     * @return 
     */
    public List<Decision> getAllCurrentDecision(Employee employee) {
        List<Decision> result = new ArrayList<>();
        List<Decision> lstAllDecision = session.getNamedQuery("HQL_ALL_DECISION").list();
        for (Decision decision : lstAllDecision) {
            if (decision.getDstate().equals("In progress")) {
                result.add(decision);
            }
        }
        return result;
    }

    /**
     * return all step validation for a department
     *
     * @param department
     * @return
     */
    public List<Stepvalidation> getAllStepValidationForDepartment(Department department) {
        List<Stepvalidation> result = new ArrayList<>();
        List<Stepvalidation> lstAllStepvalidation = session.getNamedQuery("HQL_ALL_STEPVALIDATION").list();
        for (Stepvalidation stepvalidation : lstAllStepvalidation) {
            if (stepvalidation.getDepartment().equals(department)) {
                result.add(stepvalidation);
            }
        }
        return result;
    }

    /**
     * return all current decision for the department of an employee
     *
     * @param employee
     * @return
     */
    public List<Decision> getAllCurrentDecisionForDepartment(Employee employee) {
        List<Decision> result = new ArrayList();
        for (Decision decision : this.getAllCurrentDecision(employee)) {
            if (decision.getStepvalidation().getDepartment().equals(employee.getDepartment())) {
                result.add(decision);
            }
        }
        return result;
    }

    /**
     * return a decision by his id
     * @param id
     * @return 
     */
    public Decision getDecisionById(Integer id) {
        return (Decision) session.getNamedQuery("HQL_ALL_DECISION_ID").setParameter("decisionid", id).uniqueResult();
    }

    /**
     * return all version of a document for a decision
     * @param decision
     * @return 
     */
    public List<Docversion> getAllDocversionForDecision(Decision decision) {
        return session.getNamedQuery("HQL_DOCVERSION_DECISION").setParameter("vardecision", decision).list();
    }

    /**
     * check if a step is the ended of a dap structure, by the step validation id and the dap version id
     * @param svid
     * @param dvid
     * @return 
     */
    public boolean verifstepfinal(int svid, int dvid) {
        boolean answer = false;
        Integer svidsql = (Integer) session.getNamedQuery("SQL_ORDERMAX").setParameter("idstep", dvid).uniqueResult();
        if (svid == svidsql) {
            answer = true;
        } else {
            answer = false;
        }
        return answer;

    }

    /**
     * return all dap composition
     * @param decision
     * @return 
     */
    public List<Dapcomposition> getAllDapcomposition(Decision decision) {
        return session.getNamedQuery("HQL_ALL_DAPCOMPOSITION").list();
    }

    /**
     * return all dapcomposition for a decision
     * @param decision
     * @return 
     */
    public List<Dapcomposition> getAllDapcompositionForDecision(Decision decision) {
        List<Dapcomposition> lstDapcompositionForDecision = new ArrayList<>();
        for (Dapcomposition dapcomposition : this.getAllDapcomposition(decision)) {
            if (dapcomposition.getDapstructure().equals(decision.getDapversion().getDapstructure())) {
                lstDapcompositionForDecision.add(dapcomposition);
            }
        }
        return lstDapcompositionForDecision;
    }

    /**
     * return the next dapcomposition for a decision
     * @param decision
     * @return 
     */
    public List<Stepvalidation> getNextDapComposition(Decision decision) {
        List<Stepvalidation> listRollback = new ArrayList<>();
        for (Dapcomposition dapcomposition : this.getAllDapcomposition(decision)) {
            if (dapcomposition.getStepvalidationBySvid().equals(decision.getStepvalidation())) {
                listRollback.add(dapcomposition.getStepvalidationBySvidreturn());
            }
        }
        return listRollback;
    }

    /**
     * return a stepvalidation by his id
     * @param svid
     * @return 
     */
    public Stepvalidation getStepbyid(int svid) {
        boolean trouve = false;
        int i = 0;
        int position = 0;
        while (i < getLstStepvalidation().size() && trouve == false) {
            if (getLstStepvalidation().get(i).getSvid().equals(svid)) {
                trouve = true;
                position = i;
            }
            i++;
        }

        return getLstStepvalidation().get(position);

    }

    /**
     * save a decision
     * @param decision 
     */
    public void saveNewDecision(Decision decision) {
        Transaction tr = session.beginTransaction();
        session.save(decision);
        tr.commit();
    }

    /**
     * update a decision
     * @param decision 
     */
    public void updateDecision(Decision decision) {
        Transaction tr = session.getTransaction();
        tr.begin();
        session.update(decision);
        tr.commit();
    }

    /**
     * return a list of stepvalidation
     * @return 
     */
    public List<Stepvalidation> getLstStepvalidation() {
        return session.getNamedQuery("lstStepValidation").list();
    }
}
